package ms.jacrim.pddl.evaluator;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import ms.jacrim.pddl.PddlSolution;
import ms.utils.XmlFile;

public class CostBenefitQuotient extends Evaluator {

	private final float DEFAULT_COST = .1f;
	private float totalCost, totalSat;
	private Double sat_coeff;
	private Double eff_coeff;

	public CostBenefitQuotient(float coeffience) {
		super(coeffience);
	}

	@Override
	public String Name() {
		return "CostBenefitQuotient";
	}

	public void loadConfig(String filename) throws Exception {
		config = new XmlFile(filename);
	}

	@Override
	public float evaluate(PddlSolution solution) throws Exception {
		totalCost = totalSat = 0;
		
		XPath xpath = XPathFactory.newInstance().newXPath();

		if (config == null)
			throw new Exception("Configuration of CostBenefitQuotient is not set.");
		
		sat_coeff = (Double) xpath.evaluate("//pddl/fact/@satisfaction_coeff", config.Root, XPathConstants.NUMBER);
		eff_coeff = (Double) xpath.evaluate("//pddl/fact/@work_load_coeff", config.Root, XPathConstants.NUMBER);

		for (int i = 0; i < solution.ActionCount(); i++) {
			PddlSolution.Action a = solution.getAction(i);
			if ("SATISFIES".equalsIgnoreCase(a.Name())) {
				String arg = String.format("//pddl/fact/actors/actor[@id='%s']/can_provide[@goal-id='%s']/@", a.Argument(0), a.Argument(1));
				double sat = (Double) xpath.evaluate(arg + "satisfaction", config.Root, XPathConstants.NUMBER);
				double effort = (Double) xpath.evaluate(arg + "effort", config.Root, XPathConstants.NUMBER);
				//result += sat*sat_coeff / effort*eff_coeff;
				
				totalCost += effort;
				totalSat += sat;
			} else
				totalCost += DEFAULT_COST;
				//result += DEFAULT_COST;
		}

		return Score();
	}

	@Override
	public float Score() {
		return (float) (totalSat * sat_coeff / totalCost * eff_coeff);
	}

}
